<script lang="ts" setup>
import type { VbenFormSchema } from '@vben/common-ui';
import type { Recordable } from '@vben/types';

import { computed, ref, useTemplateRef } from 'vue';
import { message } from 'ant-design-vue';
import { AuthenticationRegister, z } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { sendSmsCodeApi, registerByPhoneApi } from '#/api/core/auth';

defineOptions({ name: 'Register' });

const loading = ref(false);
const CODE_LENGTH = 6;
const registerRef = useTemplateRef<InstanceType<typeof AuthenticationRegister>>('registerRef');

async function sendCodeApi(phoneNumber: string) {
  message.loading({
    content: $t('page.auth.sendingCode'),
    duration: 0,
    key: 'sending-code',
  });
  try {
    await sendSmsCodeApi(phoneNumber);
    message.success({
      content: $t('page.auth.codeSentTo', [phoneNumber]),
      duration: 3,
      key: 'sending-code',
    });
  } catch (error) {
    message.error({
      content: $t('page.auth.sendCodeError') || 'Failed to send code. Please try again.',
      duration: 3,
      key: 'sending-code',
    });
    throw error;
  }
}

const formSchema = computed((): VbenFormSchema[] => {
  return [
    {
      component: 'VbenInput',
      componentProps: {
        placeholder: $t('authentication.mobile'),
      },
      fieldName: 'phoneNumber',
      label: $t('authentication.mobile'),
      rules: z
        .string()
        .min(1, { message: $t('authentication.mobileTip') })
        .refine((v) => /^\d{11}$/.test(v), {
          message: $t('authentication.mobileErrortip'),
        }),
    },
    {
      component: 'VbenPinInput',
      componentProps: {
        codeLength: CODE_LENGTH,
        createText: (countdown: number) => {
          const text =
            countdown > 0
              ? $t('authentication.sendText', [countdown])
              : $t('authentication.sendCode');
          return text;
        },
        handleSendCode: async () => {
          loading.value = true;
          const formApi = registerRef.value?.getFormApi();
          if (!formApi) {
            loading.value = false;
            throw new Error('formApi is not ready');
          }
          await formApi.validateField('phoneNumber');
          const isPhoneReady = await formApi.isFieldValid('phoneNumber');
          if (!isPhoneReady) {
            loading.value = false;
            throw new Error('Phone number is not Ready');
          }
          const { phoneNumber } = await formApi.getValues();
          await sendCodeApi(phoneNumber);
          loading.value = false;
        },
        placeholder: $t('authentication.code'),
      },
      fieldName: 'code',
      label: $t('authentication.code'),
      rules: z.string().length(CODE_LENGTH, {
        message: $t('authentication.codeTip', [CODE_LENGTH]),
      }),
    },
    {
      component: 'VbenInputPassword',
      componentProps: {
        placeholder: $t('authentication.password'),
      },
      fieldName: 'password',
      label: $t('authentication.password'),
      rules: z.string().min(6, { message: $t('authentication.passwordTip') }),
    },
    {
      component: 'VbenInputPassword',
      componentProps: {
        placeholder: $t('authentication.confirmPassword'),
      },
      fieldName: 'confirmPassword',
      label: $t('authentication.confirmPassword'),
      rules: z.string().min(6, { message: $t('authentication.confirmPasswordTip') }),
    },
  ];
});

async function onSubmit(params: Recordable<any>) {
  if (params.password !== params.confirmPassword) {
    message.error($t('authentication.passwordNotMatch'));
    return;
  }

  loading.value = true;
  try {
    const registerData = {
      phone: params.phoneNumber,
      password: params.password,
      code: params.code,
    };

    await registerByPhoneApi(registerData);
    message.success($t('authentication.registerSuccess'));
  } catch (error) {
    console.error('Registration failed:', error);
    message.error($t('authentication.registerFailed') || 'Registration failed. Please try again.');
  } finally {
    loading.value = false;
  }
}
</script>

<template>
  <AuthenticationRegister
    ref="registerRef"
    :form-schema="formSchema"
    :loading="loading"
    :show-third-party-login="false"
    :show-qrcode-login="false"
    :show-code-login="false"
    @submit="onSubmit"
  />
</template>
